package com.insmess.speech.sdk.template;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.insmess.speech.sdk.dto.VectorRequestDto;
import com.insmess.speech.sdk.dto.VectorResponseDto;
import com.insmess.speech.sdk.util.FileBase64Utils;
import lombok.SneakyThrows;

import java.util.HashMap;
import java.util.Map;

public class InsmessVectorTemplate {
    private String url;

    public InsmessVectorTemplate(String url) {
        this.url = url;
    }

    /**
     * 根据文件的base64进行声纹识别
     * @return
     */
    @SneakyThrows
    public Double[] vectorRequest(String file) {
        HttpRequest http = HttpUtil.createPost(url);
        //构造请求体
        Map<String, Object> params = new HashMap<>();
        String base64 = FileBase64Utils.convertFileToBase64(file);
        params.put("task", "spk");
        params.put("audio", base64);
        params.put("audio_format", "wav");
        params.put("sample_rate", 16000);
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(params);
        HttpResponse resp = http.body(json).execute();
        String body = resp.body();
        JsonNode jsonNode = objectMapper.readTree(body);
        ArrayNode vecJsonArrayNode = (ArrayNode)jsonNode.at("/result/vec");
        Double[] vecArr = new Double[vecJsonArrayNode.size()];
        for (int i = 0; i < vecJsonArrayNode.size(); i++) {
            Double vec = vecJsonArrayNode.get(i).asDouble();
            vecArr[i] = vec;
        }
        return vecArr;
    }

    /**
     * 根据文件的base64进行声纹识别
     * @return
     */
    @SneakyThrows
    public VectorResponseDto vectorCompare(Double[] vecOne, Double[] vecTwo) {
        HttpRequest http = HttpUtil.createPost(url + "/compare");
        //构造请求体
        Map<String, Object> params = new HashMap<>();
        params.put("vec_one", vecOne);
        params.put("vec_two", vecTwo);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String json = objectMapper.writeValueAsString(params);
        HttpResponse resp = http.body(json).execute();
        String body = resp.body();
        VectorResponseDto vectorResponseDto = objectMapper.readValue(body, VectorResponseDto.class);
        return vectorResponseDto;
    }

    /**
     * 根据文件的base64进行声纹对比
     * @param fileOne 文件一
     * @param fileTwo 文件二
     * @return
     */
    @SneakyThrows
    public VectorResponseDto vectorScoreRequest(String fileOne, String fileTwo) {
        HttpRequest http = HttpUtil.createPost(url + "/score");
        //构造请求体
        VectorRequestDto vectorRequestDto = new VectorRequestDto();
        String base64One = FileBase64Utils.convertFileToBase64(fileOne);
        String base64Two = FileBase64Utils.convertFileToBase64(fileTwo);
        vectorRequestDto.setEnrollAudio(base64One);
        vectorRequestDto.setTestAudio(base64Two);
        return getAsrResponseDto(http, vectorRequestDto);
    }

    /**
     * HTTP发送http请求并将结果转换
     * @param http
     * @param vectorRequestDto
     * @return
     * @throws JsonProcessingException
     */
    private VectorResponseDto getAsrResponseDto(HttpRequest http, VectorRequestDto vectorRequestDto) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String json = objectMapper.writeValueAsString(vectorRequestDto);
        HttpResponse resp = http.body(json).execute();
        String body = resp.body();
        VectorResponseDto vectorResponseDto = objectMapper.readValue(body, VectorResponseDto.class);
        return vectorResponseDto;
    }
}
